/**
 * Project: ServletDemo
 * File Created at 2012-8-24下午11:57:43
 */
package demo.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 各种关于servlet或filter的测试实例
 * 
 * @author Administrator 2012-8-24下午11:57:43
 */
public class TestFilter implements Filter {

    private ServletContext servletContext;

    /**
     * filter的初始化
     * 
     * @author Administrator 2012-8-24下午11:57:56
     */
    @Override
    public void init(FilterConfig config) throws ServletException {

        System.out.println("===> TestFilter 初始化成功！2");

        // 从 config 中获取 servletContext
        this.servletContext = config.getServletContext();
    }

    /**
     * filter的销毁
     * 
     * @author Administrator 2012-8-24下午11:57:56
     */
    @Override
    public void destroy() {
        System.out.println("===> TestFilter 销毁！2");
    }

    /**
     * filter的处理方法
     * 
     * @author Administrator 2012-8-24下午11:57:56
     */
    @Override
    public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain)
            throws IOException, ServletException {

        System.out.println("===> TestFilter 被调用！");

        // ServletResponse 转换成 HttpServletResponse、ServletRequest  转换成 HttpServletRequest
        HttpServletResponse response = (HttpServletResponse) sresponse;
        HttpServletRequest request = (HttpServletRequest) srequest;

        // 1、调用 response.sendError 设置错误信息
        setResponseError(response,false);

        // 2、调用 response 的 flushBuffer，将内容立即发到客户端
        callResponseFlushBuffer(response, false);

        // 3、Dispatching Requests
        userDispatchingRequests(request, response,0);

        chain.doFilter(srequest, sresponse);
    }

    /**
     * 1、调用 response.sendError 设置错误信息，客户端显示该设置的错误信息
     * 
     * @author Administrator 2012-8-24下午11:53:31
     * @param response
     * @throws IOException
     */
    private void setResponseError(HttpServletResponse response,boolean doTest) throws IOException {
        if(!doTest){
            return;
        }
        response.sendError(55696, "## ^-^ ^-^  this is only a test by zhaoyuanli  ^-^ ^-^ ##");
        System.out.println("  ====> setResponseError 被调用！");
        return;
    }

    /**
     * 2、调用 response的flushBuffer，直接将 response 的内容发送到客户端
     * 
     * @author Administrator 2012-8-23下午11:02:48
     * @param sresponse
     * @throws IOException
     */
    private void callResponseFlushBuffer(HttpServletResponse sresponse, boolean doTest)
            throws IOException {
        
        if (!doTest) {
            return;
        }
        
        sresponse.setContentType("text/html;charset=UTF-8");
        
        PrintWriter out = sresponse.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>response flushBuffer Test</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>response.flushBuffer() Test:EncodingFilter </h1>");
        out.println("<body>");
        out.println("</html>");
        out.close();
        
        sresponse.flushBuffer();
        
        System.out.println("  ===> callResponseFlushBuffer 被调用 ！");
    }

    /**
     * 3、Dispatching Requests 测试
     * 
     * @author Administrator 2012-9-2下午3:04:08
     * @param request
     * @param response
     * @param testno 测试的编号，0为不测试
     */
    private void userDispatchingRequests(HttpServletRequest request, HttpServletResponse response,
                                         int testno) {

        if (testno == 0) {
            return;
        }

        try {

            // 1、使用 request 调用 Dispatcher，其参数为servlet接受的路径
            RequestDispatcher rd1 = request.getRequestDispatcher("hi.htm");

            // 2、使用 servletContext 的 getRequestDispatcher 方法,其参数为servlet接受的路径映射
            RequestDispatcher rd2 = servletContext.getRequestDispatcher("/hi.htm");

            // 3、使用 servletContext 的 getNamedDispatcher 方法，其参数为容器识别的servlet名称，一般在web.xml中定义
            RequestDispatcher rd3 = servletContext.getNamedDispatcher("hello_world");

            switch (testno) {
                case 1:
                    rd1.forward(request, response);
                    break;

                case 2:
                    rd2.forward(request, response);
                    break;

                case 3:
                    rd3.forward(request, response);
                    break;
            }
            
            System.out.println("  ===> userDispatchingRequests 被调用 ！");
            
        } catch (ServletException e) {
            
            System.out.println(e.toString());
        } catch (IOException e) {
            
            System.out.println(e.toString());
        }

    }

}
